/*
 * implementation of the simulated machine.
 */

#include "machine.h"
#include "schemebase.h"
#include "debug.h"

#define FP_INITIAL 0

VirtualHardware machine ;

void pushDummyFrame(void* returnAddress)
{
	DEBUG_ENTER("pushDummyFrame sp = %d, fp = %d", machine.sp, machine.fp) ;
	DEBUG_ASSERT(machine.fp == FP_INITIAL) ;
	pushFrame(NULL, 0, emptyEnv, returnAddress);
}

void initVirtualHardware()
{
	machine.sp = 0 ;
	machine.fp = FP_INITIAL ;
	push ((void*)machine.fp);
	DEBUG_TRACE("sp = %d, fp = %d", machine.sp, machine.fp) ;
}

void cleanVirtualHardware (){
	machine.fp = (int)pop ();
	DEBUG_ASSERT(machine.fp == FP_INITIAL) ;
	DEBUG_ASSERT(machine.sp == 0);
}

void push(void *x)
{
	DEBUG_ASSERT_STACK() ;
	machine.stack[machine.sp++] = x;
}

void *pop(void)
{
	DEBUG_ASSERT_STACK() ;
	return machine.stack[--machine.sp];
}

void pushPartialFrame(Amount argCount, Environment env, void* returnAddress)
{
	push((void*)argCount);
	push(env);
	push(returnAddress);
}

void pushFrame(SchemeObject* args[], Amount argCount, Environment env, void* returnAddress)
{
	int i;
	for (i = 0 ; i < argCount ; i++)
		push(args[i]);
	pushPartialFrame(argCount, env, returnAddress) ;
}


